<?php
/**
 * Created by PhpStorm.
 * User: caoguangyang
 * Date: 2023-01-25
 * Time: 9:46
 */

namespace App\Services\Promotion;
use App\CodeResponse;
use App\Enums\GrouponEnums;
use App\Inputs\PageInput;
use App\Models\Promotion\Groupon;
use App\Models\Promotion\GrouponRules;
use App\Services\BaseServices;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\AbstractFont;
use Intervention\Image\Facades\Image;
use SimpleSoftwareIO\QrCode\Facades\QrCode;

class GrouponServices extends BaseServices
{
    /**
     * 获取团购规则
     * @param PageInput $page
     * @param array $columns
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function getGrouponRules(PageInput $page, $columns = ["*"]) {
        return GrouponRules::whereStatus(GrouponEnums::RULE_STATUS_ON)
            ->orderBy($page->sort, $page->order)
            ->paginate($page->limit, $columns, 'page', $page->page);
    }

    /**
     * 获取团购规则
     * @param $id
     * @param array $columns
     * @return GrouponRules|GrouponRules[]|Builder|Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|null
     */
    public function getGrouponRulesById($id, $columns = ["*"]) {
        return GrouponRules::query()->find($id, $columns);
    }

    /**
     * 获取参团人数
     * @param $openGrouponId
     * @return int
     */
    public function countGrouponJoin($openGrouponId) {
        return Groupon::query()->whereGrouponId($openGrouponId)
            ->where('status', '!=', GrouponEnums::STATUS_NONE)
            ->count(["id"]);
    }

    /**
     * 判断是否开团或参团
     * @param $userId
     * @param $grouponId
     * @return bool
     */
    public function isOpenOrJoin($userId, $grouponId) {
        return Groupon::query()->whereUserId($userId)
            ->where(function (Builder $builder) use ($grouponId) {
                return $builder->where('groupon_id', $grouponId)
                    ->orWhere('id', $grouponId);
            })->where("status", "!=", GrouponEnums::STATUS_NONE)->exists();
    }

    /**
     * 检测团购信息
     * @param $userId
     * @param $ruleId
     * @param null $linkId
     * @throws \App\Exceptions\BusinessException
     */
    public function checkGrouponValid($userId, $ruleId, $linkId = null) {
        // 获取团购规则
        if ($ruleId == null || $ruleId <= 0) {
            return;
        }
        $rule = $this->getGrouponRulesById($ruleId);

        if (is_null($rule)) {
            $this->throwBusinessException(CodeResponse::PARAM_ILLEGAL);
        }
        // 已下线状态
        if ($rule->status == GrouponEnums::RULE_STATUS_DOWN_EXPIRE) {
            $this->throwBusinessException(CodeResponse::GROUPON_EXPIRED);
        }

        // 管理员手动下线
        if ($rule->status == GrouponEnums::RULE_STATUS_DOWN_ADMIN) {
            $this->throwBusinessException(CodeResponse::GROUPON_EXPIRED);
        }

        // 没有成团id直接返回(表示开团验证)
        if ($linkId == null || $linkId <= 0) {
            return;
        }

        // 判断参团信息
        // 判断成团人数
        if ($this->countGrouponJoin($linkId) >= ($rule->discount_member - 1)) {
            $this->throwBusinessException(CodeResponse::GROUPON_FULL);
        }

        // 判断当前用户是否参与了该团
        if ($this->isOpenOrJoin($userId, $linkId)) {
            $this->throwBusinessException(CodeResponse::GROUPON_JOIN);
        }
        return;
    }

    public function getGroupon($id, $columns = ["*"]) {
        return Groupon::query()->find($id, $columns);
    }

    /**
     * 参团
     * @param $userId
     * @param $orderId
     * @param $ruleId
     * @param null $linkId
     * @return |null
     */
    public function openOrJoinGroupon($userId, $orderId, $ruleId, $linkId = null) {
        if ($ruleId == null || $ruleId <= 0) {
            return $linkId;
        }
        $groupon = Groupon::new();
        $groupon->order_id = $orderId;
        $groupon->user_id = $userId;
        $groupon->status = GrouponEnums::STATUS_NONE;
        $groupon->rules_id = $ruleId;

        // 开团
        if (($linkId == null) || $linkId <= 0) {
            $groupon->creator_user_id = $userId;
            $groupon->creator_user_time = Carbon::now()->toDateTimeString();
            $groupon->groupon_id = 0;
            $groupon->save();
            return $groupon->id;
        }

        // 参团
        $openGroupon = $this->getGroupon($linkId);
        $groupon->creator_user_id = $openGroupon->creator_user_id;
        $groupon->groupon_id = $linkId;
        $groupon->share_url = $openGroupon->share_url;
        $groupon->save();
        return $linkId;
    }

    public function getGrouponByOrderId($orderId) {
        return Groupon::whereOrderId($orderId)->first();
    }

    /**
     * 支付成功后，更新团购活动状态
     * @param $orderId
     * @throws \App\Exceptions\BusinessException
     */
    public function payGrouponOrder($orderId) {
        // 根据订单id获取团购规则id
        $groupon = $this->getGrouponByOrderId($orderId);
        if (is_null($groupon)) {
            return;
        }

        // groupon_id = 0 相当于开团，开团要生成分享图片
        if ($groupon->groupon_id == 0) {
            $groupon->share_url = $this->createGrouponShareImage();
        }

        $groupon->status = GrouponEnums::STATUS_ON; // 开团中;
        $isSuccess = $groupon->save();
        if (!$isSuccess) {
            $this->throwBusinessException(CodeResponse::UPDATED_FAIL);
        }
        // 开团
        if ($groupon->groupon_id == 0) {
            return;
        }

        // 根据团购规则id获取团购规则信息
        $rule = $this->getGrouponRulesById($groupon->rules_id);

        // 获取参团的人数 TODO 在这里统计是否准确
        $joinCount = $this->countGrouponJoin($groupon->groupon_id);
        if ($joinCount < $rule->discount_member - 1) {
            return ;
        }

        // 参团成功后更新状态
        $row = Groupon::query()->where(function (Builder $builder) use ($groupon) {
            return $builder->where('groupon_id', $groupon->groupon_id)
                ->orWhere("id", $groupon->groupon_id);
        })->update(['status' => GrouponEnums::STATUS_SUCCEED]);

        if ($row == 0) {
            $this->throwBusinessException(CodeResponse::UPDATED_FAIL);
        }
        return;
    }

    public function createGrouponShareImage() {
        // 单元测试暂时不生成图片，减少单测运行时间
        if (app()->environment('testing')) {
            return '';
        }
        $shareUrl = route('home.redirectShareUrl', ['type' => 'groupon', 'id' => $rules->goods_id]);
        $qrCode = QrCode::format('png')->margin(1)->size(290)->generate($shareUrl);

        $goodsImage = Image::make($rules->pic_url)->resize(660, 660);
        $image = Image::make(resource_path('image/back_groupon.png'))
            ->insert($qrCode, 'top-left', 460, 770)
            ->insert($goodsImage, 'top-left', 71, 69)
            ->text($rules->goods_name, 65, 867, function (AbstractFont $font) {
                $font->color(array(167, 136, 69));
                $font->size(28);
                $font->file(resource_path('ttf/msyh.ttf'));
            });
        $filePath = 'groupon/'.Carbon::now()->toDateString().'/'.Str::random().'.png';
        Storage::disk('public')->put($filePath, $image->encode());
        return Storage::url($filePath);
    }
}